#ifndef UTILS_H
#define UTILS_H
#include <string>
#include <vector>
#include <osg/Vec3>

bool computeIntersection2D(const osg::Vec3 &p0, const osg::Vec3 &p2,
                           const osg::Vec3 &p1, const osg::Vec3 &p3, osg::Vec3 &intersection)
{
    double x1 = p0.x(), y1 = p0.y();
    double x2 = p2.x(), y2 = p2.y();
    double x3 = p1.x(), y3 = p1.y();
    double x4 = p3.x(), y4 = p3.y();

    double denom = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4);
    if (fabs(denom) < 1e-9)
    {
        return false; // 平行或重合
    }

    double px = ((x1 * y2 - y1 * x2) * (x3 - x4) - (x1 - x2) * (x3 * y4 - y3 * x4)) / denom;
    double py = ((x1 * y2 - y1 * x2) * (y3 - y4) - (y1 - y2) * (x3 * y4 - y3 * x4)) / denom;

    // 交点 z 取平均
    double pz = (p0.z() + p1.z() + p2.z() + p3.z()) / 4.0;
    intersection = osg::Vec3(px, py, pz);
    return true;
}

static std::vector<double> make_clamped_uniform(int degree, int nctl)
{
    int k = nctl + degree + 1;
    std::vector<double> U(k, 0.0);
    int span = k - 2 * (degree + 1);
    if (span > 0)
        for (int i = 1; i <= span; ++i)
            U[degree + i] = double(i) / (span + 1);
    for (int i = k - degree - 1; i < k; ++i)
        U[i] = 1.0;
    return U;
}


/* ========== 路径 B：Catmull-Rom（镜像端点，无越界） ========== */
std::vector<osg::Vec3d> pad_catmull(const std::vector<osg::Vec3d> &in, bool closed)
{
    if (closed)
        return in;
    std::vector<osg::Vec3d> out;
    out.reserve(in.size() + 2);
    out.push_back(in[0] * 2 - in[1]); // p_{-1}
    out.insert(out.end(), in.begin(), in.end());
    out.push_back(in[in.size() - 1] * 2 - in[in.size() - 2]); // p_{n}
    return out;
}


static double bspline_basis(int i, int k, double t, const double *knots, int num_knots)
{
    if (k == 1)
    {
        if (knots[i] <= t && t < knots[i + 1])
            return 1.0;
        // 处理最后一个节点收敛
        if (i == num_knots - 2 && fabs(t - knots[num_knots - 1]) < 1e-12)
            return 1.0;
        return 0.0;
    }
    else
    {
        double denom1 = knots[i + k - 1] - knots[i];
        double denom2 = knots[i + k] - knots[i + 1];
        double term1 = 0.0, term2 = 0.0;
        if (denom1 > 1e-12)
            term1 = (t - knots[i]) / denom1 * bspline_basis(i, k - 1, t, knots, num_knots);
        if (denom2 > 1e-12)
            term2 = (knots[i + k] - t) / denom2 * bspline_basis(i + 1, k - 1, t, knots, num_knots);
        return term1 + term2;
    }
}

// NURBS插值，支持权重
static osg::Vec3d deBoorEval(
    int degree, int num_ctrl_pts,
    const Dwg_SPLINE_control_point *ctrl_pts,
    const double *knots, int num_knots,
    double t)
{
    double denom = 0.0;
    osg::Vec3d result(0, 0, 0);
    for (int i = 0; i < num_ctrl_pts; ++i)
    {
        double Ni = bspline_basis(i, degree + 1, t, knots, num_knots);
        double w = ctrl_pts[i].w;
        result += osg::Vec3d(ctrl_pts[i].x, ctrl_pts[i].y, ctrl_pts[i].z) * (Ni * w);
        denom += Ni * w;
    }
    if (denom > 1e-12)
        result /= denom;
    return result;
}

// 处理MTEXT格式代码的函数
std::string processMTextFormatting(const std::string &input)
{
    std::string result = input;

    // 处理换行符
    size_t pos = 0;
    while ((pos = result.find("\\P", pos)) != std::string::npos)
    {
        result.replace(pos, 2, "\n");
        pos += 1;
    }

    // 处理其他格式代码（可选）
    // 例如：\\O 和 \\o 用于上标和下标
    // \\L 和 \\l 用于划线
    // \\K 用于堆叠分数等

    return result;
}
#endif